package com.ruoyi.common.utils.ps2;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class RobustImageDPIUpdater{

    public static void main(String[] args) {
        String sourceFolderPath = "C:\\Users\\xinhuiRong\\Desktop\\东南亚-女";
        String targetFolderPath = "C:\\Users\\xinhuiRong\\Desktop\\东南亚-女\\DPI";
        int newDPI = 300;

        try {
            updateImagesDPI(sourceFolderPath, targetFolderPath, newDPI);
            System.out.println("DPI更新完成！");
        } catch (IOException e) {
            System.err.println("处理图片时出错: " + e.getMessage());
        }
    }

    public static void updateImagesDPI(String sourceFolderPath, String targetFolderPath, int newDPI) throws IOException {
        File sourceFolder = new File(sourceFolderPath);
        File targetFolder = new File(targetFolderPath);

        if (!targetFolder.exists() && !targetFolder.mkdirs()) {
            throw new IOException("无法创建目标文件夹: " + targetFolderPath);
        }

        if (!sourceFolder.isDirectory()) {
            throw new IllegalArgumentException("提供的源路径不是文件夹: " + sourceFolderPath);
        }

        List<File> imageFiles = findImageFiles(sourceFolder);
        if (imageFiles.isEmpty()) {
            System.out.println("源文件夹中没有找到支持的图片文件");
            return;
        }

        for (File imageFile : imageFiles) {
            try {
                processSingleImage(imageFile, targetFolder, newDPI);
            } catch (Exception e) {
                System.err.println("处理图片 " + imageFile.getName() + " 时出错: " + e.getMessage());
            }
        }
    }

    private static void processSingleImage(File imageFile, File targetFolder, int dpi) throws IOException {
        BufferedImage image = ImageIO.read(imageFile);
        if (image == null) {
            throw new IOException("无法读取图片: " + imageFile.getName());
        }

        String formatName = getImageFormatName(imageFile);
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);

        if (!writers.hasNext()) {
            throw new IOException("找不到适合的ImageWriter处理: " + imageFile.getName());
        }

        ImageWriter writer = writers.next();
        IIOMetadata metadata = writer.getDefaultImageMetadata(
                new javax.imageio.ImageTypeSpecifier(image),
                null
        );

        // 尝试设置DPI，如果失败则继续处理
        try {
            setDPISafely(metadata, dpi);
        } catch (Exception e) {
            System.err.println("警告: 无法为 " + imageFile.getName() + " 设置DPI (" + e.getMessage() + ")，将继续保存图片");
        }

        File targetFile = new File(targetFolder, imageFile.getName());
        try (ImageOutputStream out = ImageIO.createImageOutputStream(targetFile)) {
            writer.setOutput(out);
            writer.write(metadata, new javax.imageio.IIOImage(image, null, metadata), null);
        }

        System.out.println("已处理: " + imageFile.getName());
    }

    private static void setDPISafely(IIOMetadata metadata, int dpi) throws IIOInvalidTreeException {
        String metadataFormat = "javax_imageio_1.0";
        org.w3c.dom.Node tree = metadata.getAsTree(metadataFormat);

        if (tree == null) {
            throw new IllegalStateException("无法获取图像元数据树");
        }

        org.w3c.dom.Element root = (org.w3c.dom.Element) tree;
        org.w3c.dom.Document doc = root.getOwnerDocument();

        if (doc == null) {
            throw new IllegalStateException("元数据树没有关联的文档对象");
        }

        double dotsPerMillimeter = dpi / 25.4;
        String pixelSizeValue = String.valueOf(1 / dotsPerMillimeter);

        // 处理水平DPI
        org.w3c.dom.NodeList hNodes = root.getElementsByTagName("HorizontalPixelSize");
        if (hNodes.getLength() > 0) {
            ((org.w3c.dom.Element)hNodes.item(0)).setAttribute("value", pixelSizeValue);
        } else {
            org.w3c.dom.Element hElement = doc.createElement("HorizontalPixelSize");
            hElement.setAttribute("value", pixelSizeValue);
            root.appendChild(hElement);
        }

        // 处理垂直DPI
        org.w3c.dom.NodeList vNodes = root.getElementsByTagName("VerticalPixelSize");
        if (vNodes.getLength() > 0) {
            ((org.w3c.dom.Element)vNodes.item(0)).setAttribute("value", pixelSizeValue);
        } else {
            org.w3c.dom.Element vElement = doc.createElement("VerticalPixelSize");
            vElement.setAttribute("value", pixelSizeValue);
            root.appendChild(vElement);
        }

        metadata.mergeTree(metadataFormat, tree);
    }

    private static List<File> findImageFiles(File folder) {
        List<File> imageFiles = new ArrayList<>();
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile() && isImageFile(file)) {
                    imageFiles.add(file);
                }
            }
        }
        return imageFiles;
    }

    private static boolean isImageFile(File file) {
        String name = file.getName().toLowerCase();
        return name.endsWith(".jpg") || name.endsWith(".jpeg") ||
                name.endsWith(".png") || name.endsWith(".bmp") ||
                name.endsWith(".gif") || name.endsWith(".tiff");
    }

    private static String getImageFormatName(File file) {
        String name = file.getName().toLowerCase();
        if (name.endsWith(".jpg") || name.endsWith(".jpeg")) return "JPEG";
        if (name.endsWith(".png")) return "PNG";
        if (name.endsWith(".bmp")) return "BMP";
        if (name.endsWith(".gif")) return "GIF";
        if (name.endsWith(".tiff")) return "TIFF";
        return "JPEG";
    }
}